package com.ruibang.glass.quality.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.quality.component.job.DataDispose;
import com.ruibang.glass.quality.constant.Constants;
import com.ruibang.glass.quality.domain.req.DefectGroupReq;
import com.ruibang.glass.quality.domain.req.DiscardDefectReq;
import com.ruibang.glass.quality.entity.Defect;
import com.ruibang.glass.quality.entity.DefectGroup;
import com.ruibang.glass.quality.mapper.DefectGroupMapper;
import com.ruibang.glass.quality.service.DefectGroupService;
import com.ruibang.glass.quality.service.DefectService;
import com.ruibang.glass.quality.service.TotalEquDataService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruibang.glass.quality.constant.QualityErrorCode;

import java.io.Serializable;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @Author: songJinKang
 * @CreateTime: 2023-08-30  14:41
 * @Description: TODO:
 * @Version: 1.0
 */

@Slf4j
@Service
public class DefectGroupServiceImpl extends ServiceImpl<DefectGroupMapper, DefectGroup> implements DefectGroupService {

    @Autowired
    private DefectService defectService;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

//    @Autowired
//    private RedisSingleService redisService;

    @Autowired
    private RedisSingleService redisService;

    @Autowired
    @Lazy
    private DataDispose dataDispose;


    /**
     * @Description: 查询缺陷组
     * @version v1.0
     * @author songJinKang
     * @date 2023-08-30 14:58
     */
    @Override
    public ResultBody queryDefectGroup(DefectGroupReq defectGroupReq) {
        QueryWrapper<DefectGroup> dgQw = new QueryWrapper<>();
        dgQw.lambda().like(StringUtils.isNotBlank(defectGroupReq.getDefectGroupName()), DefectGroup::getDefectGroupName, defectGroupReq.getDefectGroupName());
        final IPage<DefectGroup> page = baseMapper.selectPage(new Page<>(defectGroupReq.getPageNo(), defectGroupReq.getPageSize()), dgQw);
        //缺陷信息
        List<DefectGroup> records = page.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            List<String> groupIds = records.stream().map(DefectGroup::getDefectGroupId).collect(Collectors.toList());
            List<Defect> defects = defectService.getByDefectGroupId(groupIds);
            if (CollectionUtils.isNotEmpty(defects)) {
                Map<String, List<Defect>> defectMap = defects.stream().collect(Collectors.groupingBy(Defect::getDefectGroupId));
                for (DefectGroup record : records) {
                    List<Defect> defect = defectMap.get(record.getDefectGroupId());
                    if (CollectionUtils.isNotEmpty(defect)) {
                        record.setDefects(defect);
                    }
                }
            }
        }
        return ResultBody.success(page);
    }

    /**
     * @Description: 获取检查机
     * @version v1.0
     * @author songJinKang
     * @date 2023-08-30 15:10
     */
    @Override
    public ResultBody getCheckMachine() {
        return ResultBody.success(baseMapper.getCheckMachine());
    }

    /**
     * @Description: 添加缺陷组
     * @version v1.0
     * @author songJinKang
     * @date 2023-08-30 15:47
     */
    @Override
    public ResultBody insert(DefectGroup defectGroup) {
        try {
            this.save(defectGroup);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                return ResultBody.fail(QualityErrorCode.CHECK_CHECK_MACHINE_IS_EXIST.getCode(), QualityErrorCode.CHECK_CHECK_MACHINE_IS_EXIST.getMsg());
            }
            return ResultBody.fail(QualityErrorCode.ERROR.getCode(), QualityErrorCode.ERROR.getMsg());
        }
        return ResultBody.success();
    }


    /**
     * @Description: 根据检查机code获取缺陷组
     * @version v1.0
     * @author songJinKang
     * @date 2023-08-30 15:50
     */
    @Override
    public List<Defect> getByCheckMachine(String code, String type) {
        if (StringUtils.isNotBlank(code)) {
            //获取缺陷组
            QueryWrapper<DefectGroup> dgQw = new QueryWrapper<>();
            dgQw.lambda().eq(DefectGroup::getCheckMachineCode, code);
            dgQw.lambda().eq(DefectGroup::getCheckMachineType, type);
            DefectGroup defectGroup = this.getOne(dgQw);
            if (defectGroup != null) {
                //获取缺陷
                return defectService.getByGroupId(defectGroup.getDefectGroupId());
            }
        }
        return Collections.emptyList();
    }

    /**
     * @Description: 根据缺陷组id删除
     * @version v1.0
     * @author songJinKang
     * @date 2023-08-30 16:23
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String defectGroupId) {
        if (StringUtils.isNotBlank(defectGroupId)) {
            //删除缺陷组
            this.removeById(defectGroupId);
            //删除缺陷
            defectService.deleteByDefectGroupId(defectGroupId);
        }
    }

    /**
     * @Description: 根据id获取详情
     * @version v1.0
     * @author songJinKang
     * @date 2023-08-30 16:28
     */
    @Override
    public ResultBody getDetail(String defectGroupId) {
        if (StringUtils.isNotBlank(defectGroupId)) {
            DefectGroup defectGroup = this.getById(defectGroupId);
            if (defectGroup != null) {
                List<Defect> defects = defectService.getByDefectGroupId(Collections.singletonList(defectGroup.getDefectGroupId()));
                defectGroup.setDefects(defects);
            }
            return ResultBody.success(defectGroup);
        }
        return ResultBody.success();
    }

    /**
     * @Description: 更新缺陷组
     * @version v1.0
     * @author songJinKang
     * @date 2023-08-31 16:41
     */
    @Override
    public ResultBody edit(DefectGroup defectGroup) {
        if (StringUtils.isNotBlank(defectGroup.getDefectGroupId())) {
            DefectGroup groupData = this.getById(defectGroup.getDefectGroupId());
            String key = String.format(RedisKey.DEFECT_GROUP_IS_RUN, defectGroup.getCheckMachineCode());
            if (groupData != null) {
                String oldTime = groupData.getTakingEffectTime().toString();
                String newTime = defectGroup.getTakingEffectTime().toString();
                if (!oldTime.equals(newTime)) {
                    //判断当前是否执行数据更新任务
                    Serializable value = redisService.get(key);
                    if (value != null && StringUtils.isNotBlank(value.toString())) {
                        throw new ServiceException(QualityErrorCode.DEFECT_TASK_IS_RUN.getCode(), QualityErrorCode.DEFECT_TASK_IS_RUN.getMsg());
                    }

                    //执行热端任务
                    if (defectGroup.getCheckMachineType().equals(Constants.ONE_STR)) {
                        CompletableFuture.runAsync(() -> dataDispose.hotTask(defectGroup.getTakingEffectTime(), LocalDate.now()), threadPoolTaskExecutor);
                    } else {
                        //执行冷端任务
                        CompletableFuture.runAsync(() -> dataDispose.coldTask(defectGroup.getTakingEffectTime(), LocalDate.now()), threadPoolTaskExecutor);
                    }

                    redisService.set(key, "1", 10 * 60);
                }
            }
            //更新缺陷组
            this.updateById(defectGroup);
        }
        return ResultBody.success();
    }

}
